// axios的处理
import axios from 'axios'
import { message } from '@/utils/functions'
// 导入pinia实例
import { useUserStore } from '@/stores/user'
// 导入路由
import router from '@/router'

// 配置基准地址,有些情况这个地址需要被其他地方使用，所以导出去
export const baseURL = 'http://localhost:8888/api/private/v1'
const request = axios.create({
    // axios 的一些配置，baseURL  timeout
    baseURL,
    // 请求的超时时间
    timeout: 5000
})

// 添加请求拦截器
request.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么,比如需要登录才能发起的请求，可以在请求头中添加token需要进行登录校验的接口，
    // 在请求时都需要在请求头中携带token，去后端api中做token校验
    const token = useUserStore().token
    if (token && config.url !== '/login') {
        // 在请求头中添加token
        config.headers.Authorization = token
    }
    // 在发送请求之前做些什么
    return config;
}, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});

// 添加响应拦截器
request.interceptors.response.use(function (response) {
    // 返回的数据,都是HTTP状态码为200的响应
    const {
        data: { data, meta }
    } = response
    // meta中的status是业务状态码
    // 拦截401
    if (meta.status == 401) {
        // TODO
        message('error', '登录过期，请重新登录')
        return Promise.reject(new Error('token异常,请先登录'))
    }
    // 拦截400
    if (meta.status == 400) {
        if (meta.msg === '无效token') {
            // 调接口时，发现token异常，出现的情况可能有以下几种：
            // 1.token突然失效，此时需要重新登录
            // 2.token过期，此时需要重新登录
            // 3.token被修改，此时需要重新登录

            // 移动端的处理方式：无感登录
            // 无感登录：用户登录成功后，后端会下发2个token，一个是进行接口校验的token，一个是刷新refresh_token,token的内容都是根据登录
            // 用户的信息进行生成的，只不过，token的有效时长一般是2小时，refresh_token的过期时间是7天
            // 当我们检查到token异常时，应该先判断有没有刷新token，如果有，就使用刷新token，然后重新请求一次接口，生成新的token，

            // PC端的处理方式：弹出登录框，让用户重新登录
            // 如果刷新token也过期了，就直接跳转登录页
            message('error', meta.msg)
            router.push('/login')
            return Promise.reject(new Error(meta.msg))
        }
        // 其他的错误
        return Promise.reject(new Error(meta.msg))
    }

    // 拦截
    if (meta.status == 403) {
        message('error', meta.msg)
        // TODO
        return Promise.reject(new Error('没有权限'))
    }

    // 拦截404
    if (meta.status == 404) {
        message('error', meta.msg)
        // TODO
        return Promise.reject(new Error('请求地址不存在'))
    }
    // 拦截500
    if (meta.status == 500) {
        message('error', meta.msg)
        // TODO
        return Promise.reject(new Error('服务器异常'))
    }

    // 响应成功
    return data;
}, function (error) {
    // 服务器返回的HTTP状态码非200的响应
    return Promise.reject(error);
});


// 封装统一的请求函数
// url：请求的地址；method:请求方式；submitData: 请求的数据，必须是一个对象
export default (url, method, submitData) => {
    // 根据请求方式是否是get请求，来判断要用params还是data传递参数
    const dataType = method.toLowerCase() === 'get' ? 'params' : 'data'
    return request({
        'method': method,
        'url': url,
        // 变量作为对象的键使用时，必须使用中括号
        [dataType]: submitData,
    })
}